package com.lhh.videoservice.service.Impl;

import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhh.springcommon.annotation.WebLog;
import com.lhh.springcommon.entity.Collect;
import com.lhh.springcommon.entity.Like;
import com.lhh.springcommon.entity.Video;
import com.lhh.springcommon.entity.vo.CountVideoInfoVO;
import com.lhh.springcommon.entity.vo.VideoVO;
import com.lhh.springcommon.exception.CustomException;
import com.lhh.springcommon.mapper.VideoMapper;
import com.lhh.springcommon.service.ICollectService;
import com.lhh.springcommon.service.ILikeService;
import com.lhh.springcommon.service.IVideoService;
import com.lhh.springcommon.utils.CodeEnum;
import com.lhh.springcommon.utils.Oss;
import com.lhh.springcommon.utils.PageQuery;
import com.lhh.videoservice.service.VideoPlayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @author 李厚航
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class VideoPlayServiceImpl implements VideoPlayService {

    private final IVideoService videoService;

    private final VideoMapper videoMapper;

    private final OSS ossClient;

    private final ICollectService collectService;

    private final ILikeService likeService;

    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;

    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;

    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;

    @Value("${spring.cloud.alicloud.oss.prefix}")
    private String prefix;

    @Autowired
    public VideoPlayServiceImpl(IVideoService videoService,
                                VideoMapper videoMapper,
                                OSS ossClient,
                                ICollectService collectService,
                                ILikeService likeService) {
        this.videoService = videoService;
        this.videoMapper = videoMapper;
        this.ossClient = ossClient;
        this.collectService = collectService;
        this.likeService = likeService;
    }

    @Override
    @WebLog
    @Cacheable(value = "queryAllVideoClassification", unless = "#result == null")
    public List<String> queryAllVideoClassification() {
        return videoMapper.queryAllVideoClassification();
    }

    @Override
    @WebLog
    @Caching(
            evict = {
                    @CacheEvict(value = "video", allEntries = true),
                    @CacheEvict(value = "countPublish", allEntries = true)
            }
    )
    public Video addVideo(Video video) {
        if(videoService.save(video)){
            return video;
        }
        throw new CustomException(CodeEnum.VIDEO_ADDITION_FAILED);
    }

    @Override
    @WebLog
    public Page<VideoVO> queryPageVideo(PageQuery<Video> page) {
        return videoMapper.queryPageVideoVO(page.getQueryInfo(), new Page<>(page.getPage(), page.getPageSize()));
    }

    @Override
    @WebLog
    @CacheEvict(value = "video", allEntries = true)
    public Boolean deleteVideo(Video video) {
        return videoService.remove(new LambdaQueryWrapper<Video>()
                .eq(video.getId() != null, Video::getId, video.getId())
                .eq(video.getPublisherId() != null, Video::getPublisherId, video.getPublisherId()));
    }

    @Override
    @WebLog
    public Map<String, String> upload() {
        return Oss.policy(ossClient,bucket,endpoint,accessId,prefix);
    }

    @Override
    @WebLog
    public CountVideoInfoVO countVideoInfo(Integer vid) {
        //获取收藏数和点赞数
        return new CountVideoInfoVO(
                collectService.count(new LambdaQueryWrapper<Collect>()
                        .eq(Collect::getVid, vid)),
                likeService.count(new LambdaQueryWrapper<Like>()
                        .eq(Like::getVid, vid))
        );
    }
}
